/*
 * Cursor.java  0.4.0 / Oct 26, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.swing;

/**
 * Cursor Class.
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public class Cursor {

// Public Static Fields. -------------------------------------------------------

  /**
   * The default cursor type.
   */
  public static final int DEFAULT_CURSOR = 0;

  /**
   * The crosshair cursor type.
   */
  public static final int CROSSHAIR_CURSOR = 1;

  /**
   * The text cursor type.
   */
  public static final int TEXT_CURSOR = 2;

  /**
   * The wait cursor type.
   */
  public static final int WAIT_CURSOR = 3;

  /**
   * The south-west-resize cursor type.
   */
  public static final int SW_RESIZE_CURSOR = 4;

  /**
   * The south-east-resize cursor type.
   */
  public static final int SE_RESIZE_CURSOR = 5;

  /**
   * The north-west-resize cursor type.
   */
  public static final int NW_RESIZE_CURSOR = 6;

  /**
   * The north-east-resize cursor type.
   */
  public static final int NE_RESIZE_CURSOR = 7;

  /**
   * The north-resize cursor type.
   */
  public static final int N_RESIZE_CURSOR = 8;

  /**
   * The south-resize cursor type.
   */
  public static final int S_RESIZE_CURSOR = 9;

  /**
   * The west-resize cursor type.
   */
  public static final int W_RESIZE_CURSOR = 10;

  /**
   * The east-resize cursor type.
   */
  public static final int E_RESIZE_CURSOR = 11;

  /**
   * The hand cursor type.
   */
  public static final int HAND_CURSOR = 12;

  /**
   * The move cursor type.
   */
  public static final int MOVE_CURSOR = 13;

  /**
   * The up arrow cursor type.
   */
  public static final int UP_ARROW_CURSOR = 14;

  /**
   * The forbidden cursor type.
   */
  public static final int FORBIDDEN_CURSOR = 15;

  /**
   * The whats this cursor type.
   */
  public static final int WHATS_THIS_CURSOR = 16;

  /**
   * The vertical split cursor type.
   */
  public static final int V_SPLIT_CURSOR = 17;

  /**
   * The horizontal cursor type.
   */
  public static final int H_SPLIT_CURSOR = 18;

  /**
   * The blank cursor type.
   */
  public static final int BLANK_CURSOR = 19;

  /**
   * The blank cursor type.
   */
  public static final int CUSTOM_CURSOR = 20;

// Private Static Fields. ------------------------------------------------------

  private static final Cursor[] PREDEFINED_CURSORS;
  private static final String[] CURSOR_NAMES;

// Static Initialization. ------------------------------------------------------

  static {
    PREDEFINED_CURSORS = new Cursor[20];
    CURSOR_NAMES = new String[] {
        "Default Cursor",
        "Crosshair Cursor",
        "Text Cursor",
        "Wait Cursor",
        "Southwest Resize Cursor",
        "Southeast Resize Cursor",
        "Northwest Resize Cursor",
        "Northeast Resize Cursor",
        "North Resize Cursor",
        "South Resize Cursor",
        "West Resize Cursor",
        "East Resize Cursor",
        "Hand Cursor",
        "Move Cursor",
        "Up Arrow Cursor",
        "Forbidden Cursor",
        "Whats This Cursor",
        "Vertical Split Cursor",
        "Horizontal Split Cursor",
        "Blank Cursor"
    };
  }

// Package-Private Fields. -----------------------------------------------------

  final int type;
  final String name;

// Public Constructors. --------------------------------------------------------

  /**
   * Constructs new Cursor object.
   *
   * @param type the cursor type
   *
   * @throws IllegalArgumentException if the type is invalid
   */
  public Cursor(int type) {
    if ((type < DEFAULT_CURSOR) || (type > BLANK_CURSOR)) {
      throw new IllegalArgumentException("Invalid cursor type");
    }
    this.type = type;
    name = CURSOR_NAMES[type];
  }

// Package-Private Constructors. -----------------------------------------------

  // TODO: implement custom cursors

  Cursor(String name) {
    if (name == null) {
      throw new IllegalArgumentException("Null cursor name");
    }
    this.type = CUSTOM_CURSOR;
    this.name = name;
  }

// Public Methods. -------------------------------------------------------------

  /**
   * Returns cursor type.
   *
   * @return cursor type
   */
  public int getType() {
    return type;
  }

  /**
   * Returns cursor name.
   *
   * @return cursor name
   */
  public String getName() {
    return name;
  }

// Public Static Methods. ------------------------------------------------------

  /**
   * Returns predefined cursor.
   *
   * @param type the cursor type
   *
   * @return predefined cursor
   *
   * @throws IllegalArgumentException if the type is invalid
   */
  public static Cursor getPredefinedCursor(int type) {
    if ((type < DEFAULT_CURSOR) || (type > BLANK_CURSOR)) {
      throw new IllegalArgumentException("Invalid cursor type");
    }
    synchronized (PREDEFINED_CURSORS) {
      if (PREDEFINED_CURSORS[type] == null) {
        PREDEFINED_CURSORS[type] = new Cursor(type);
      }
      return PREDEFINED_CURSORS[type];
    }
  }

  /**
   * Returns the system default cursor.
   *
   * @return the system default cursor.
   */
  public static Cursor getDefaultCursor() {
    return getPredefinedCursor(DEFAULT_CURSOR);
  }

// Overridden Methods. ---------------------------------------------------------

  /**
   * {@inheritDoc}
   */
  public int hashCode() {
    if (type == CUSTOM_CURSOR) {
      return name.hashCode();
    }
    return type;
  }

  /**
   * {@inheritDoc}
   */
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if ((obj != null) && (obj.getClass() == getClass())) {
      Cursor cursor = (Cursor)obj;
      if (type == CUSTOM_CURSOR) {
        return ((cursor.type == CUSTOM_CURSOR) && name.equals(cursor.name));
      }
      return (type == cursor.type);
    }
    return false;
  }

  /**
   * {@inheritDoc}
   */
  public String toString() {
    return (getClass() + "[type=" + type + ",name=" + name + "]");
  }

}
